﻿using System;
using GeoAPI.Geometries;

namespace NetTopologySuite.Algorithm
{
	public static class AngleUtility
	{
		public static double ToDegrees(double radians)
		{
			return radians * 180.0 / System.Math.PI;
		}

		public static double ToRadians(double angleDegrees)
		{
			return angleDegrees * System.Math.PI / 180.0;
		}

		public static double Angle(Coordinate p0, Coordinate p1)
		{
			double x = p1.X - p0.X;
			return Math.Atan2(p1.Y - p0.Y, x);
		}

		public static double Angle(Coordinate p)
		{
			return Math.Atan2(p.Y, p.X);
		}

		public static bool IsAcute(Coordinate p0, Coordinate p1, Coordinate p2)
		{
			double num = p0.X - p1.X;
			double num2 = p0.Y - p1.Y;
			double num3 = p2.X - p1.X;
			double num4 = p2.Y - p1.Y;
			return num * num3 + num2 * num4 > 0.0;
		}

		public static bool IsObtuse(Coordinate p0, Coordinate p1, Coordinate p2)
		{
			double num = p0.X - p1.X;
			double num2 = p0.Y - p1.Y;
			double num3 = p2.X - p1.X;
			double num4 = p2.Y - p1.Y;
			return num * num3 + num2 * num4 < 0.0;
		}

		public static double AngleBetween(Coordinate tip1, Coordinate tail, Coordinate tip2)
		{
			double ang = AngleUtility.Angle(tail, tip1);
			double ang2 = AngleUtility.Angle(tail, tip2);
			return AngleUtility.Diff(ang, ang2);
		}

		public static double AngleBetweenOriented(Coordinate tip1, Coordinate tail, Coordinate tip2)
		{
			double num = AngleUtility.Angle(tail, tip1);
			double num2 = AngleUtility.Angle(tail, tip2) - num;
			if (num2 <= -System.Math.PI)
			{
				return num2 + System.Math.PI*2;
			}
			if (num2 > System.Math.PI)
			{
				return num2 - System.Math.PI*2;
			}
			return num2;
		}

		public static double InteriorAngle(Coordinate p0, Coordinate p1, Coordinate p2)
		{
			double num = AngleUtility.Angle(p1, p0);
			return System.Math.Abs(AngleUtility.Angle(p1, p2) - num);
		}

		public static Orientation GetTurn(double ang1, double ang2)
		{
			double num = Math.Sin(ang2 - ang1);
			if (num > 0.0)
			{
				return Orientation.CounterClockwise;
			}
			if (num < 0.0)
			{
				return Orientation.Clockwise;
			}
			return Orientation.None;
		}

		public static double Normalize(double angle)
		{
			while (angle > System.Math.PI)
			{
				angle -= System.Math.PI*2;
			}
			while (angle <= -System.Math.PI)
			{
				angle += System.Math.PI*2;
			}
			return angle;
		}

		public static double NormalizePositive(double angle)
		{
			if (angle < 0.0)
			{
				while (angle < 0.0)
				{
					angle += System.Math.PI*2;
				}
				if (angle >= System.Math.PI*2)
				{
					angle = 0.0;
				}
			}
			else
			{
				while (angle >= System.Math.PI*2)
				{
					angle -= System.Math.PI*2;
				}
				if (angle < 0.0)
				{
					angle = 0.0;
				}
			}
			return angle;
		}

		public static double Diff(double ang1, double ang2)
		{
			double num;
			if (ang1 < ang2)
			{
				num = ang2 - ang1;
			}
			else
			{
				num = ang1 - ang2;
			}
			if (num > System.Math.PI)
			{
				num = System.Math.PI*2 - num;
			}
			return num;
		}

		public const double PiTimes2 = System.Math.PI*2;

		public const double PiOver2 = System.Math.PI*.5;

		public const double PiOver4 = 0.78539816339744828;
	}
}
